class Demo {
    constructor() {
        this.video = document.querySelector("video")
        this.baseUrl = '../res/demo_dashinit.mp4';
        this.mimeCodec = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
        this.mediaSource = null;
        this.sourceBuffer = null;
        this.videoByteLength = 0
        this.cursor = 0
        this.init();
    }

    init = () => {
        if ('MediaSource' in window && MediaSource.isTypeSupported(this.mimeCodec)) {
            const mediaSource = new MediaSource();
            this.video.src = URL.createObjectURL(mediaSource); // 返回object url
            this.mediaSource = mediaSource;
            mediaSource.addEventListener('sourceopen', this.sourceOpen); // 监听sourceopen事件
        } else {
            console.error('不支持MediaSource');
        }
    }

    sourceOpen = async () => {
        // 返回sourceBuffer
        this.videoByteLength = await this.getVideoByteLength();
        this.sourceBuffer = this.mediaSource.addSourceBuffer(this.mimeCodec);
        const start = 0;
        const end = Math.min(1024 * 1024 * 3 - 1, this.videoByteLength - 1); // 加载视频开头的5M数据。如果你的视频文件很大，5M也许无法启动视频，可以适当改大点
        const range = `${start}-${end}`;
        this.cursor = end + 1
        const initData = await this.fetchVideo(range);
        this.sourceBuffer.appendBuffer(initData);
        this.sourceBuffer.addEventListener('updateend', this.updateFunct, false);
    }

    updateFunct = async () => {
        console.log(this.cursor / this.videoByteLength * 100 + "%")
        if (this.cursor > this.videoByteLength - 1){
            return
        }
        const start = this.cursor;
        const end = Math.min(this.cursor + 1024 * 1024 * 3 - 1, this.videoByteLength - 1); // 加载视频开头的5M数据。如果你的视频文件很大，5M也许无法启动视频，可以适当改大点
        const range = `${start}-${end}`;
        this.cursor = end + 1
        const initData = await this.fetchVideo(range);
        this.sourceBuffer.appendBuffer(initData);
    }

    fetchVideo = (range) => {
        const url = this.baseUrl;
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', url);
            xhr.setRequestHeader("Range", "bytes=" + range); // 添加Range头
            xhr.responseType = 'arraybuffer';
            xhr.onload = function (e) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    return resolve(xhr.response);
                }
                return reject(xhr);
            };

            xhr.onerror = function () {
                reject(xhr);
            };
            xhr.send();
        })
    }

    getVideoByteLength = () => {
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.open('GET', this.baseUrl);
            xhr.onload = function (e) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    return resolve(e.total);
                }
                return reject(xhr);
            };
            xhr.send();
        });
    }
}

const demo = new Demo()